Distributed applications which concentrate on point-to-point data transmission can often be adequately and efficiently handled using special-purpose protocols for remote terminal access and file transfer. Such protocols are tailored specifically to the one application and do not provide a foundation on which to build a variety of distributed applications (e.g., distributed operating systems, electronic mail systems, computer conferencing systems, etc.).
While conventional transport services can be used as the basis for building distributed applications, these services exhibit many organizational problems, such as the use of different data types in different machines, synchronization, and the provision of a simple programming paradigm.
Distributed systems usually contain a number of different types of machines interconnected by communications networks. Each machine has its own internal data types, its own address alignment rules, and its own operating system. This heterogeneity causes problems when building distributed systems. As a result, application developers must include in applications developed for such heterogeneous distributed systems the capability of dealing with partial failures of the distributed system and providing adequate process synchronization.
However, one simplification is afforded by noting that a large proportion of applications use a request and response interaction between processes where the initiator (i.e., application initiating a communication) is idle until the response is returned. This can be modelled by a procedure call mechanism between processes. One such mechanism is referred to as the remote procedure call (RPC).
An RPC mechanism permits a language level call on one machine to be turned automatically into a language level call in a process (i.e., application) on another machine. (The RPC mechanism may also be used between applications running on the same machine.)
The RPC is a mechanism for providing synchronized type-safe communication between two processes. In the simplest case, one process, i.e., a client application, sends a message to another process, i.e., a server application. In this case it is not necessary for the processes to be synchronized either when the message is sent or received. It is possible for the client application to transmit the message and then begin a new activity, or for the server application's environment to buffer the incoming message until the server application is ready to process a new message. RPC, however, imposes constraints on synchronism because it closely models the local procedure call, which requires passing parameters in one direction, blocking the calling process (i.e., the client application) until the called procedure (i.e., the server application) is complete, and then returning a response. RPC thus involves two message transfers, and the synchronization of the two processes for the duration of the call.
The RPC mechanism is usually implemented in two processing parts using the local procedure call paradigm, one part being on the client side and the other part being on the server side. Both of these parts will be described below with reference to FIG. 1.
FIG. 1 is a diagram illustrating the flow of call information using an RPC mechanism. As shown in FIG. 1, a client application 100 issues a call (step 102). The RPC mechanism 101 then packs the call as arguments of a call packet (step 103), which the RPC mechanism 101 then transmits to a server application 109 (step 104). The call packet is used to identify the client application 100 that first sent the call. After the call packet is transmitted (step 104), the RPC mechanism 101 enters a wait state during which it waits for a response from the server application 109.
The RPC mechanism 108 for the server application 109 (which may be the same RPC mechanism as the RPC mechanism 101 when the server application 109 is on the same platform as the client application 100) receives the call packet (step 110), unpacks the arguments of the call from the call packet (step 111), identifies, using the call arguments, the server application 109 to which the call was addressed, and provides the call arguments to the server application 109.
The server application receives the call (step 112), processes the call (step 115), and returns a response to the RPC 108 (step 116). The RPC 108 then packs the response in a response packet (step 114) and transmits it to the client application 100 (step 113).
Receiving the response packet (step 107) triggers the RPC mechanism 101 to exit the waft state and unpack the response from the response packet (step 106). The RPC 101 then provides the response to the client application 100 in response to the call (step 105). This is the process flow of the typical RPC mechanism modelled after the local procedure call paradigm. Since the RPC mechanism uses the local procedure call paradigm, the client application 100 is blocked at the call until a response is received. Thus, the client application 100 does not continue with its own processing after sending the call; rather, it waits for a response from the server application 109.
Synchronization between client and server applications tends to waste processing cycles. Accordingly, asynchronous communication is the preferred method for communicating among applications in a distributed system.
The Java.TM. programming language is an object-oriented programming language that is described, for example, in a text entitled "The Java Language Specification" by James Gosling, Bill Joy, and Guy Steele, Addison-Wesley, 1996. This language is typically compiled to a universal executable format, using a "bytecode instruction set," which can be executed on any platform supporting the Java virtual machine (JVM). The JVM is described, for example, in a text entitled "The Java Virtual Machine Specification," by Tim Lindholm and Frank Yellin, Addison Wesley, 1996. Because the JVM may be implemented on any type of platform, implementing distributed applications using the JVM significantly reduces the difficulties associated with developing applications for heterogenous distributed systems. Moreover, the JVM uses a Java remote method invocation (RMI) that enables synchronous communication among applications of the system.
FIG. 2 is a diagram illustrating the flow of objects in an object-oriented distributed system 200 including machines 201 and 202 for transmitting and receiving objects using the JVM. In network 200 machine 201 uses RMI 205 for responding to a call for object 203 by converting the object into a byte stream 207 including an identification of the type of object transmitted and data constituting the object. Java RMIs are known in the art and an exemplary explanation is available from Sun Microsystems, Inc. and is also currently available via the Internet at the address "http://java.sun.com/products/jdk/rmi/index.html." While machine 201 is responding to the call for object 203, a process running on the same or another machine in system 200 may continue operation without waiting for a response to its request.
Machine 202 receives the byte stream 207. Using RMI 206, machine 202 automatically converts it into the corresponding object 204, which is a copy of object 203 and which makes the object available for use by an application executing on machine 202. Machine 202 may also transmit the object to another machine by first converting the object into a byte stream and then sending it to the third machine, which also automatically converts the byte stream into the corresponding object.
The automatic reconstruction of the objects from the byte stream in this manner sometimes requires unnecessary processing. For example, there are times when a call is made that does not require actual or immediate interaction with the object, both of which require conversion of the byte stream to object form. Instead, a call may require passing the object to another call or storing it for later use. In this situation, the reconstruction of the object on an intermediate machine is unnecessary, especially if the object is to be transmitted to another machine. Accordingly, it is desirable to more efficiently transmit objects in a distributed system without the unneeded conversion of a byte stream to an object on intermediate machines that have no use for the object, or the premature conversion of the byte stream before a process on the receiving machine requires access to the object.